/**
 * Created by gongxun on 17/7/30.
 */

var CardType = {};
CardType.error = 0;                     //错误牌型
CardType.single = 1;                    //单张
CardType.pair = 2;                      //对子
CardType.triple = 3;                    //三张
CardType.tripleSingle = 4;              //三带一		//可以带任意1张牌 可选	2选1
CardType.tripleTwoSingle = 5;           //三带二		//可以带任意2张牌	可选 2选1
CardType.tripleTwoPair = 6;             //三带二            //取消
CardType.fourSingle = 7;                //四带二            //取消
CardType.fourPair = 8;                  //四带两对          //取消
CardType.fourThree = 9;                 //四带三            //可选
CardType.straight = 10;                 //顺子
CardType.straightPair = 11;             //连对
CardType.straightTriple = 12;           //三连对
CardType.airplaneSingle = 13;           //飞机带翅膀单翼 可以带n个单牌 可选 2选1
CardType.airplanePair = 14;             //飞机带翅膀双翼 可以带n个对子 可选 2选1
CardType.airplaneEx = 15;               //飞机带翅膀EX n>1时 可以带2 				//取消
CardType.bomb = 16;                     //炸弹

var CardTypeString = [
    "错误牌型",
    "单张",
    "对子",
    "三张",
    "三带一",
    "三带二",
    "四带二",
    "四带两对",
    "四带三",
    "顺子",
    "连对",
    "三连对",
    "飞机带翅膀 带单",
    "飞机带翅膀 带双",
    "飞机带翅膀 特殊",
    "炸弹"
];

var PdzCardRule = function () {
    var that = {};

    //更具规则获取可用牌型
    that.GetCardTypesForRule = function(cfg){
        var cfgs = [];

        cfgs.push(CardType.single);
        cfgs.push(CardType.pair);
        cfgs.push(CardType.triple);
        cfgs.push(CardType.straight);
        cfgs.push(CardType.straightPair);
        cfgs.push(CardType.straightTriple);

        //三带
        if (cfg.ruletriple == 0){
            cfgs.push(CardType.tripleSingle);
        }else if (cfg.ruletriple == 1){
            cfgs.push(CardType.tripleTwoSingle);
        }

        //四带三
        if (cfg.rulefour == 0){
            cfgs.push(CardType.fourThree);
        }

        //飞机
        if (cfg.ruleairplane == 0){
            cfgs.push(CardType.airplaneSingle);
        }else if (cfg.ruleairplane == 1){
            cfgs.push(CardType.airplanePair);
        }

        cfgs.push(CardType.bomb);

        return cfgs;
    };

    //检测牌型是否合法 返回牌型
    that.checkCardType = function (nums) {
        return that.getCardType(nums);
    };

    //检测能否出牌
    that.checkCardTypePlay = function (nums1, nums2) {
        var num = that.checkCardTypeBiggerNum(nums1, nums2);
        cc.log("给出的1:" + nums1.valueOf() + "给出的2:" + nums2.valueOf() + "\n返回值:" + num);
        return num > 0;
    };

    //检测要不要的起
    that.checkCanPlay = function (nums, inhandNums) {
        var result = [];

        cc.log("nums:" + nums.valueOf());
        cc.log("inhandNums:" + inhandNums.valueOf());

        var cardType = that.getCardType(nums);
        if (cardType == CardType.error) {
            cc.error("没有找到这个类型的");
            return result;
        }
        cc.log("给的牌型是" + CardTypeString[cardType]);

        //对应的值
        var zhiNums = [];
        for (var i = 0; i < nums.length; i++) {
            zhiNums.push(that.getCardNumMax(nums[i]).zhi);
        }
        zhiNums.sort(function (a, b) {
            return a - b;
        });


        //对应牌型的所有可能
        var possibleZhis = that.getPossibleForCardType(cardType, inhandNums, nums.length);

        for (var i = 0; i < possibleZhis.length; i++) {
            var sortZhiNums = possibleZhis[i].slice(0);
            sortZhiNums.sort(function (a, b) {
                return a - b;
            });
            var isBigger = that.getIsZhi2Bigger(zhiNums, sortZhiNums, cardType);
            if (isBigger > 0) {
                result = result.concat([sortZhiNums]);
            }
        }

        //检测炸弹的特殊情况
        if (cardType != CardType.bomb) {
            //炸弹
            result = result.concat(that.getPossibleForCardType(CardType.bomb, inhandNums));
        }

        cc.log("可以出的牌");
        cc.log(result.valueOf());
        cc.log("可以出的牌");

        return result;
    };

    //检测能否出单牌
    that.checkIsPlaySing = function (cardNums, lastCardsLength, playNums) {
        if (playNums.length == 1 && lastCardsLength == 1) {
            var myZhi = that.getCardNumMax(playNums[0]).zhi;

            for (var i = 0; i < cardNums.length; i++) {
                var zhi = that.getCardNumMax(cardNums[i]).zhi;
                if (zhi > myZhi) {
                    return false;
                }
            }
        }

        return true;
    };

    //通过值找手牌
    that.getCardNumsForZhiNums = function (zhinums, inhandnums) {
        var result = [];

        //备用
        var cardNums = inhandnums.slice(0);
        mo.pdkCardHelper.sortCardEx(cardNums);

        for (var i = 0; i < zhinums.length; i++) {
            var zhi = zhinums[i];

            for (var j = 0; j < cardNums.length; j++) {
                if (zhi == that.getCardNumMax(cardNums[j]).zhi) {
                    result.push(cardNums[j]);
                    cardNums.splice(j, 1);
                    break;
                }
            }
        }

        if (result.length == zhinums.length) {
            return result;
        } else {
            return [];
        }
    };

    //检测给出的牌中是否有给定值
    that.checkCardNumIncludeNum = function (cardNums, num) {
        for (var i = 0; i < cardNums.length; i++) {
            if (cardNums[i] == num) {
                return true;
            }
        }
        return false;
    };

    //返回牌值大小 从3,4,5,6-j,q,k,A 值对应0-11 2对应20 王对应53 54
    that.getCardNumMax = function (num) {
        var result = {};
        result.old = num;
        result.zhi = 0;

        if (num > 52) {
            return num
        }
        var temp = (num - 1) % 13;
        if (temp == 0) {
            temp = 11;
        } else if (temp == 1) {
            temp = 20;
        } else {
            temp -= 2
        }
        result.zhi = temp;
        return result;
    };

    //返回牌型
    that.getCardType = function (nums) {
        if (nums == null || nums == undefined || nums.length == 0) {
            return CardType.error;
        }

        //计算实际值
        var zhiNums = [];
        for (var i = 0; i < nums.length; i++) {
            zhiNums.push(that.getCardNumMax(nums[i]).zhi);
        }
        zhiNums.sort(function (a, b) {
            return a - b;
        });

        //查看可以组合的牌型
        var cardType = CardType.error;

        for (var i = 1; i <= CardType.bomb; i++) {
            if (that.getIsCardType(zhiNums, i)) {
                cardType = i;
                break;
            }
        }

        // cc.log("给出的:" + nums.valueOf() + "值为:" + zhiNums.valueOf() + "\n牌型为:" + CardTypeString[cardType]);

        return cardType;
    };

    //返回是否是当前牌型 zhiNums是从小到大排序的
    that.getIsCardType = function (zhiNums, cardType) {

        switch (cardType) {
            case CardType.single:
                //单张
                if (zhiNums.length == 1) {
                    return true;
                }

                break;
            case CardType.pair:
                //对子
                if (zhiNums.length == 2) {
                    if (zhiNums[0] == zhiNums[1]) {
                        return true
                    }
                }

                break;
            case CardType.triple:
                //三张
                if (zhiNums.length == 3) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getNDaiMPossible(zhiMap, zhiNums, 3, 0, false, false);
                    if (result.length == 1) {
                        if (result[0][0] != 11) {
                            return true
                        }
                    } else if (result.length != 0) {
                        return true;
                    }
                }
                break;
            case CardType.tripleSingle:
                //三带一
                if (zhiNums.length == 4) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getNDaiMPossible(zhiMap, zhiNums, 3, 1, false, true);
                    if (result.length != 0) {
                        return true;
                    }
                }

                break;
            case CardType.tripleTwoSingle:
                //三带二 单
                if (zhiNums.length == 5) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getNDaiMPossible(zhiMap, zhiNums, 3, 2, false, true);
                    if (result.length != 0) {
                        return true;
                    }
                }

                break;
            case CardType.tripleTwoPair:
                // //三带二 双
                // if (zhiNums.length == 5) {
                //     var zhiMap = that.getZhiMap(zhiNums);
                //     var result = that.getNDaiMPossible(zhiMap, zhiNums, 3, 1, true, false);
                //     if (result.length != 0) {
                //         return true;
                //     }
                // }

                break;
            case CardType.fourSingle:
                //四带二 取消
                // if (zhiNums.length == 6) {
                //     var zhiMap = that.getZhiMap(zhiNums);
                //     var result = that.getNDaiMPossible(zhiMap, zhiNums, 4, 2, false);
                //     if (result.length != 0) {
                //         return true;
                //     }
                // }

                break;
            case CardType.fourPair:
                //四带二对 取消
                // if (zhiNums.length == 8) {
                //     var zhiMap = that.getZhiMap(zhiNums);
                //     var result = that.getNDaiMPossible(zhiMap, zhiNums, 4, 2, true);
                //     if (result.length != 0) {
                //         return true;
                //     }
                // }

                break;
            case CardType.fourThree:
                //四带三
                if (zhiNums.length == 7) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getNDaiMPossible(zhiMap, zhiNums, 4, 3, false, true);
                    if (result.length != 0) {
                        return true;
                    }
                }

                break;
            case CardType.straight:
                //顺子
                if (zhiNums.length >= 5) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getLianxuPossible(zhiMap, zhiNums, zhiNums.length, 1);
                    if (result.length != 0) {
                        return true;
                    }
                }

                break;
            case CardType.straightPair:
                //连对
                if (zhiNums.length >= 4 && zhiNums.length % 2 == 0) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getLianxuPossible(zhiMap, zhiNums, parseInt(zhiNums.length / 2), 2);
                    if (result.length != 0) {
                        return true;
                    }
                }

                break;
            case CardType.straightTriple:
                //三连对
                if (zhiNums.length >= 6 && zhiNums.length % 3 == 0) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getLianxuPossible(zhiMap, zhiNums, parseInt(zhiNums.length / 3), 3);
                    if (result.length != 0) {
                        return true;
                    }
                }

                break;
            case CardType.airplaneSingle:
                //飞机带翅膀 带单
                if (zhiNums.length >= 8 && zhiNums.length % 4 == 0) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getAirplanePossible(zhiMap, zhiNums, parseInt(zhiNums.length / 4), parseInt(zhiNums.length / 4), false, true);
                    if (result.length != 0) {
                        return true;
                    }
                }
                break;
            case CardType.airplanePair:
                //飞机带翅膀 带双
                if (zhiNums.length >= 10 && zhiNums.length % 5 == 0) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getAirplanePossible(zhiMap, zhiNums, parseInt(zhiNums.length / 5), parseInt(zhiNums.length / 5) * 2, true, true);
                    if (result.length != 0) {
                        return true;
                    }
                }

                break;
            case CardType.airplaneEx:
                //飞机带翅膀 带双
                if (zhiNums.length >= 8 && (zhiNums.length - 2) % 3 == 0) {
                    var zhiMap = that.getZhiMap(zhiNums);
                    var result = that.getAirplanePossible(zhiMap, zhiNums, parseInt((zhiNums.length - 2) / 3), 2, false, true);
                    if (result.length != 0) {
                        return true;
                    }
                }

                break;
            case CardType.bomb:
                //炸弹
                // if (zhiNums.length == 3) {
                //     var map = that.getZhiMap(zhiNums);
                //     for (var key in map) {
                //         if (map.hasOwnProperty(key)) {
                //             if (map[key] == 3 && parseInt(key) == 11) {
                //                 return true;
                //             }
                //         }
                //     }
                // }

                if (zhiNums.length == 4) {
                    var map = that.getZhiMap(zhiNums);
                    for (var key in map) {
                        if (map.hasOwnProperty(key)) {
                            if (map[key] == 4) {
                                return true;
                            }
                        }
                    }
                }

                break;
        }


        return false;
    };

    //检测牌型大小 0等于 1大于 -1小于 比如 num2比num1大 返回1
    that.checkCardTypeBiggerNum = function (nums1, nums2) {
        var cardType1 = that.getCardType(nums1);
        var cardType2 = that.getCardType(nums2);

        //牌型的差值
        var cardTypeOffset = cardType2 - cardType1;
        if (cardTypeOffset != 0) {
            if (cardType1 == CardType.bomb || cardType2 == CardType.bomb) {
                return cardType2 - cardType1;
            } else {
                return 0;
            }
        } else {
            var zhiNums1 = [];
            for (var i = 0; i < nums1.length; i++) {
                zhiNums1.push(that.getCardNumMax(nums1[i]).zhi);
            }
            zhiNums1.sort(function (a, b) {
                return a - b;
            });

            var zhiNums2 = [];
            for (var i = 0; i < nums2.length; i++) {
                zhiNums2.push(that.getCardNumMax(nums2[i]).zhi);
            }
            zhiNums2.sort(function (a, b) {
                return a - b;
            });

            return that.getIsZhi2Bigger(zhiNums1, zhiNums2, cardType1);
        }
    };

    //返回zhinums2是否比1大 大1 小-1 等于0 zhiNums是从小到大排序的
    that.getIsZhi2Bigger = function (zhiNums1, zhiNums2, cardType) {
        switch (cardType) {
            case CardType.single:
                //单张
                return zhiNums2[0] - zhiNums1[0];
                break;
            case CardType.pair:
                //对子
                return zhiNums2[0] - zhiNums1[0];
                break;
            case CardType.triple:
                //三张
                return zhiNums2[0] - zhiNums1[0];
                break;
            case CardType.tripleSingle:
                //三带一
                return that.getNDaiMKeyValue(zhiNums2, 3) - that.getNDaiMKeyValue(zhiNums1, 3);
                break;
            case CardType.tripleTwoSingle:
                //三带二
                return that.getNDaiMKeyValue(zhiNums2, 3) - that.getNDaiMKeyValue(zhiNums1, 3);
                break;
            case CardType.tripleTwoPair:
                //三带二
                return that.getNDaiMKeyValue(zhiNums2, 3) - that.getNDaiMKeyValue(zhiNums1, 3);
                break;
            case CardType.fourSingle:
                //四带二
                return that.getNDaiMKeyValue(zhiNums2, 4) - that.getNDaiMKeyValue(zhiNums1, 4);
                break;
            case CardType.fourPair:
                //四带对子
                return that.getNDaiMKeyValue(zhiNums2, 4) - that.getNDaiMKeyValue(zhiNums1, 4);
                break;
            case CardType.fourThree:
                //四带带三
                return that.getNDaiMKeyValue(zhiNums2, 4) - that.getNDaiMKeyValue(zhiNums1, 4);
                break;
            case CardType.straight:
                //顺子
                return zhiNums2[zhiNums2.length - 1] - zhiNums1[zhiNums1.length - 1];
                break;
            case CardType.straightPair:
                //连对
                return zhiNums2[zhiNums2.length - 1] - zhiNums1[zhiNums1.length - 1];
                break;
            case CardType.straightTriple:
                //三顺子
                return zhiNums2[zhiNums2.length - 1] - zhiNums1[zhiNums1.length - 1];
                break;
            case CardType.airplaneSingle:
                //飞机带翅膀 单
                return that.getAirplaneKeyValue(zhiNums2, parseInt(zhiNums2.length / 5)) - that.getAirplaneKeyValue(zhiNums1, parseInt(zhiNums1.length / 5));
                break;
            case CardType.airplanePair:
                //飞机带翅膀 双
                return that.getAirplaneKeyValue(zhiNums2, parseInt(zhiNums2.length / 5)) - that.getAirplaneKeyValue(zhiNums1, parseInt(zhiNums1.length / 5));
                break;
            case CardType.airplaneEx:
                return that.getAirplaneKeyValue(zhiNums2, parseInt((zhiNums2.length - 2) / 3)) - that.getAirplaneKeyValue(zhiNums1, parseInt((zhiNums1.length - 2) / 3));
                break;
            case CardType.bomb:
                //炸弹
                return zhiNums2[zhiNums2.length - 1] - zhiNums1[zhiNums1.length - 1];
                break;
        }

        return 0;
    };

    //返回对应牌型在手牌中的所有可能情况 返回对应的值的二维数组
    that.getPossibleForCardType = function (cardType, nums, otherLen) {
        var result = [];

        if (nums == null || nums == undefined || nums.length == 0) {
            return [];
        }

        //计算实际值
        var zhiNums = [];
        for (var i = 0; i < nums.length; i++) {
            zhiNums.push(that.getCardNumMax(nums[i]).zhi);
        }
        zhiNums.sort(function (a, b) {
            return a - b;
        });
        var zhiMap = that.getZhiMap(zhiNums);

        if (cardType == CardType.single) {
            //单张
            for (key in zhiMap) {
                if (zhiMap.hasOwnProperty(key)) {
                    var zhi = parseInt(key);
                    result.push([zhi]);
                }
            }
        } else if (cardType == CardType.pair) {
            //对子
            for (key in zhiMap) {
                if (zhiMap.hasOwnProperty(key)) {
                    var zhi = parseInt(key);
                    var count = zhiMap[key];
                    if (count >= 2) {
                        result.push([zhi, zhi]);
                    }
                }
            }

        } else if (cardType == CardType.triple) {
            //三张
            result = that.getNDaiMPossible(zhiMap, zhiNums, 3, 0, false, false);
        } else if (cardType == CardType.tripleSingle) {
            //三带1
            result = that.getNDaiMPossible(zhiMap, zhiNums, 3, 1, false, false);
        } else if (cardType == CardType.tripleTwoSingle) {
            //三带2
            result = that.getNDaiMPossible(zhiMap, zhiNums, 3, 2, false, true);
        } else if (cardType == CardType.tripleTwoPair) {
            //三带2
            result = that.getNDaiMPossible(zhiMap, zhiNums, 3, 1, true, true);
        } else if (cardType == CardType.fourSingle) {
            //四带2张
            result = that.getNDaiMPossible(zhiMap, zhiNums, 4, 2, false, false);
        } else if (cardType == CardType.fourPair) {
            //四带2对
            result = that.getNDaiMPossible(zhiMap, zhiNums, 4, 2, true, false);
        } else if (cardType == CardType.fourThree) {
            //四带三
            result = that.getNDaiMPossible(zhiMap, zhiNums, 4, 3, false, true);
        } else if (cardType == CardType.straight) {
            //顺子
            result = that.getLianxuPossible(zhiMap, zhiNums, otherLen, 1);
        } else if (cardType == CardType.straightPair) {
            //连对
            result = that.getLianxuPossible(zhiMap, zhiNums, parseInt(otherLen / 2), 2);
        } else if (cardType == CardType.straightTriple) {
            //三连对
            result = that.getLianxuPossible(zhiMap, zhiNums, parseInt(otherLen / 3), 3);
        } else if (cardType == CardType.airplaneSingle) {
            //飞机带翅膀 带单
            result = that.getAirplanePossible(zhiMap, zhiNums, parseInt(otherLen / 4), parseInt(otherLen / 4), false, true);
        } else if (cardType == CardType.airplanePair) {
            //飞机带翅膀 带双
            result = that.getAirplanePossible(zhiMap, zhiNums, parseInt(otherLen / 5), parseInt(otherLen / 5 * 2), true, true);
        } else if (cardType == CardType.airplaneEx) {
            //飞机带翅膀 特殊
            result = that.getAirplanePossible(zhiMap, zhiNums, parseInt((otherLen - 2) / 3), 2, false, true);
        } else if (cardType == CardType.bomb) {
            //炸弹
            for (key in zhiMap) {
                if (zhiMap.hasOwnProperty(key)) {
                    var zhi = [parseInt(key)];
                    var count = zhiMap[key];

                    if (count >= 4) {
                        result.push([zhi, zhi, zhi, zhi]);
                    }
                }
            }
        }


        return result;
    };

    //返回手牌值以及对应情况
    that.getZhiMap = function (zhiNums) {
        var map = {};
        for (var i = 0; i < zhiNums.length; i++) {
            var key = zhiNums[i].toString();
            if (map[key] == undefined) {
                map[key] = 0;
            }
            map[key]++;
        }
        return map;
    };

    //返回出现最多的值
    that.getZhiCountMaxBig = function (zhiNums) {
        var map = that.getZhiMap(zhiNums);
        //出现次数最多的次数 和大小
        var count = -1;
        var max = -1;
        for (key in map) {
            if (map.hasOwnProperty(key)) {
                if (map[key] > count) {
                    count = map[key];
                    max = parseInt(key);
                } else if (map[key] == count) {
                    if (parseInt(key) > max) {
                        max = parseInt(key);
                    }
                }
            }
        }
        return max;
    };

    //找到飞机带翅膀中决定性的值
    that.getAirplaneKeyValue = function (zhiNums, len) {
        var zhimap = that.getZhiMap(zhiNums);
        var triple = that.getLianxuPossible(zhimap, zhiNums, len, 3);

        var key = -1;
        for (var i = 0; i < triple.length; i++) {
            if (triple[i][0] > key) {
                key = triple[i][0];
            }
        }

        return key;
    };

    //找到n带m决定性的值
    that.getNDaiMKeyValue = function (zhiNums, n) {
        var zhimap = that.getZhiMap(zhiNums);
        for (key in zhimap) {
            if (zhimap.hasOwnProperty(key)) {
                if (zhimap[key] == n) {
                    return parseInt(key);
                }
            }
        }

        return 0;
    };

    //返回n带m的情况 isPair是否对子 isAnyDai (特殊 m不能和n一样)
    that.getNDaiMPossible = function (zhiMap, zhiNums, n, m, isPair, isAnyDai) {
        var result = [];

        var timesDai = isPair ? 2 : 1;

        var len = n + timesDai * m;
        if (zhiNums < len) {
            return result;
        }

        for (key in zhiMap) {
            if (zhiMap.hasOwnProperty(key)) {
                var zhi = parseInt(key);
                var count = zhiMap[key];

                if (count >= n) {
                    var userZhi = {};                   //用了的
                    var userCount = 0;                  //找到的m次数
                    var minCount = isPair ? 2 : 1;      //带的最小重复

                    for (var i = 0; i < m; i++) {
                        for (itemKey in zhiMap) {
                            if (zhiMap.hasOwnProperty(itemKey)) {
                                var itemZhi = parseInt(itemKey);
                                var itemCount = zhiMap[itemKey];

                                //zhi里面不存在 且大于带的数量
                                if (itemKey != zhi && itemCount >= minCount) {

                                    //不存在
                                    if (userZhi[itemKey] == undefined) {
                                        userZhi[itemKey] = minCount;
                                        userCount += 1;
                                        break;
                                    }

                                    if (isAnyDai) {
                                        //存在 但是手牌中足够多
                                        if (userZhi[itemKey] + minCount <= zhiMap[itemKey]) {
                                            userZhi[itemKey] += minCount;
                                            userCount += 1;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (userCount == m) {
                        var item = [];
                        for (var i = 0; i < n; i++) {
                            item.push(zhi);
                        }
                        for (userKey in userZhi) {
                            if (userZhi.hasOwnProperty(userKey)) {
                                for (var i = 0; i < userZhi[userKey]; i++) {
                                    item.push(parseInt(userKey));
                                }
                            }
                        }
                        result.push(item);
                    }
                }
            }
        }

        return result;
    };

    //返回连续情况 len连续长度    count每个连续数量
    that.getLianxuPossible = function (zhiMap, zhiNums, len, count) {
        var result = [];

        var zhis = [];
        for (key in zhiMap) {
            if (zhiMap.hasOwnProperty(key)) {
                if (zhiMap[key] >= count) {
                    var zhi = parseInt(key);
                    zhis.push(zhi);
                }
            }
        }
        zhis.sort(function (a, b) {
            return a - b;
        });

        //找到手牌中连续超过len张的牌
        for (var i = 0; i < zhis.length; i++) {
            var isOk = true;
            var num = zhis[i];
            var temp = [];
            for (var x = 0; x < count; x++) {
                temp.push(num);
            }
            for (var j = 1; j < len; j++) {
                var index = i + j;
                var yuqiNum = num + j;
                if (index >= zhis.length) {
                    isOk = false;
                    break;
                }

                if (zhis[index] != yuqiNum) {
                    isOk = false;
                    break;
                }

                for (var x = 0; x < count; x++) {
                    temp.push(yuqiNum);
                }
            }

            if (isOk) {
                result.push(temp);
            }
        }

        return result;
    };

    //返回飞机带翅膀的情况 len连续长度 isPair带的是单还是双 (带的牌 不能是3连一样)
    that.getAirplanePossible = function (zhiMap, zhiNums, len, lenDai, isPair, isAnyDai) {
        //返回结果
        var result = [];

        //找到所有3连情况
        var tripleLists = that.getLianxuPossible(zhiMap, zhiNums, len, 3);

        //带的最小重复
        var minCount = isPair ? 2 : 1;

        //寻找次数
        var findCount = isPair ? lenDai / 2 : lenDai;

        for (var i = 0; i < tripleLists.length; i++) {
            var triple = tripleLists[i];

            var userZhi = {};                   //用了的
            var userCount = 0;                  //找到的m次数
            //寻找剩下的牌
            for (var j = 0; j < findCount; j++) {
                for (itemKey in zhiMap) {
                    if (zhiMap.hasOwnProperty(itemKey)) {
                        var itemZhi = parseInt(itemKey);
                        var itemCount = zhiMap[itemKey];

                        //不和3连的牌一样 且大于带的数量
                        if (triple.indexOf(itemZhi) == -1 && itemCount >= minCount) {

                            //不存在
                            if (userZhi[itemKey] == undefined) {
                                userZhi[itemKey] = minCount;
                                userCount += minCount;
                                break;
                            }

                            //存在 但是手牌中足够多
                            if (isAnyDai) {
                                if (userZhi[itemKey] + minCount <= zhiMap[itemKey]) {
                                    userZhi[itemKey] += minCount;
                                    userCount += minCount;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            if (userCount == lenDai) {
                var item = [].concat(triple);
                for (userKey in userZhi) {
                    if (userZhi.hasOwnProperty(userKey)) {
                        for (var i = 0; i < userZhi[userKey]; i++) {
                            item.push(parseInt(userKey));
                        }
                    }
                }
                result.push(item);
            }
        }

        return result;
    };

    that.test = function () {
        // cc.log("check cardType...................");
        // that.getCardType([2]);
        // that.getCardType([1, 14]);
        // that.getCardType([1, 14, 40, 2]);
        // that.getCardType([1, 14, 40, 2, 15]);
        // that.getCardType([1, 14, 27, 40, 2, 3]);
        // that.getCardType([1, 14, 27, 40, 2, 15, 3, 16]);
        // that.getCardType([3, 4, 5, 6, 7, 8]);
        // that.getCardType([3, 16, 4, 17]);                 //连对
        // that.getCardType([3, 16, 29, 4, 17, 30, 5, 6]);                 //飞机带翅膀带单
        // that.getCardType([3, 16, 29, 4, 17, 30, 5, 6, 18, 19]);                 //飞机带翅膀带双
        // that.getCardType([1, 14, 27]);
        // that.getCardType([3, 16, 29, 42]);
        //
        // //特殊情况
        // that.getCardType([1, 13, 12, 11, 10]);
        // that.getCardType([1, 2, 13, 12, 11, 10]);
        // cc.log("check cardType...................");

        // cc.log("check bigger...................");
        // that.checkCardTypePlay([3], [1]);
        // that.checkCardTypePlay([3, 16], [1, 14]);
        // that.checkCardTypePlay([3, 16, 29, 4], [1, 14, 27, 2]);
        // that.checkCardTypePlay([3, 16, 29, 4, 17], [1, 14, 27, 2, 15]);
        // that.checkCardTypePlay([3, 16, 29, 42, 6, 5], [1, 14, 27, 40, 5, 4]);
        // that.checkCardTypePlay([3, 16, 29, 42, 6, 5, 19, 18], [1, 14, 27, 40, 2, 3, 15, 16]);
        // that.checkCardTypePlay([3, 4, 5, 6, 7, 8], [1, 13, 12, 11, 10]);
        // that.checkCardTypePlay([3, 4, 5, 6, 7], [1, 13, 12, 11, 10, 9]);
        // that.checkCardTypePlay([3, 16, 29, 42], [1, 14, 27]);
        // cc.log("check bigger...................");


        // cc.log("check canPlay...............................");
        // that.checkCanPlay([8, 21, 34], [4, 17, 30, 9, 22, 35, 6, 7, 8]);
        // cc.log("check canPlay...............................");
        //
        // cc.log("check canPlay...............................");
        // that.checkCanPlay([8, 21, 34, 3], [4, 17, 30, 9, 22, 35, 6, 7, 8]);
        // cc.log("check canPlay...............................");
        //
        // cc.log("check canPlay...............................");
        // that.checkCanPlay([8, 21, 34, 3, 16], [4, 17, 30, 9, 22, 35, 6, 7, 8]);
        // cc.log("check canPlay...............................");

        // cc.log("check canPlay...............................");
        // that.checkCanPlay([8, 21, 34], [7, 20, 33, 46, 9, 22, 35, 48]);
        // cc.log("check canPlay...............................");
        //
        // cc.log("check canPlay...............................");
        // that.checkCanPlay([8, 21, 34, 9], [7, 20, 33, 46, 9, 22, 35, 48]);
        // cc.log("check canPlay...............................");
        //
        // cc.log("check canPlay...............................");
        // that.checkCanPlay([8, 21, 34, 47, 3, 16], [7, 20, 33, 46, 9, 22, 35, 48]);
        // cc.log("check canPlay...............................");
        //
        // cc.log("check canPlay...............................");
        // that.checkCanPlay([3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8, 9]);
        // cc.log("check canPlay...............................");
        //
        // cc.log("check canPlay...............................");
        // that.checkCanPlay([3, 3, 4, 4, 5, 5], [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6]);
        // cc.log("check canPlay...............................");


        cc.log("check canPlay...............................");
        that.checkCanPlay([3, 3, 3, 4, 4, 4, 5, 6], [1, 1, 1, 13, 13, 13, 2, 3]);
        cc.log("check canPlay...............................");

        cc.log("check canPlay...............................");
        that.checkCanPlay([3, 3, 3, 4, 4, 4, 5, 6, 5, 6], [1, 1, 1, 13, 13, 13, 2, 3, 3, 4, 4]);
        cc.log("check canPlay...............................");

        cc.log("check canPlay...............................");
        that.checkCanPlay([3, 3, 3, 4, 4, 4, 5, 5, 5, 5], [7, 7, 7, 8, 8, 8, 3, 3, 4, 4]);
        cc.log("check canPlay...............................");

        cc.log("check canPlay...............................");
        that.checkCanPlay([49, 11, 37, 50], [36, 33, 52, 40, 18, 23, 30, 10, 9, 7, 32, 4, 44, 46, 47, 48]);
        cc.log("check canPlay...............................");
    };

    return that;
};

mo.pdkCardRule = new PdzCardRule();